package Improve;

import Imp.*;

import java.io.IOException;
import java.util.Properties;
import java.util.function.Function;

/**
 * @author zhaoren
 * @version 1.0
 * @description 这里设计成简单工厂模式的样子先看看优劣，
 * @date 2020/7/29 13:44
 **/
public class DataAccess {

    /**
     * 这是事先指定好的数据库，这里就直接在配置文件中实现定义了，更改数据库的时候连具体的类都不用改，只需要改变
     * 配置文件中的配置即可，大大降低了耦合度
     */
    private static final String DB;

    /**
     * 在类初始化的时候就加载配置文件中的值然后设置进去
     */
    static {
        Properties properties = new Properties();
        try {
            properties.load(ClassLoader.getSystemResourceAsStream("database.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        DB = (String) properties.get("database.Name");
    }

    public static IUserOperation createUserOperation() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        IUserOperation userOperation = null;
        //可以看到使用了简单工厂的方式进行改进的话如果用switch case将会有比较大的代码量，下面考虑用反射来改进一下
//        switch (DB){
//            case "SqlServer":
//                userOperation = new SqlServerUserOperationImp();
//                break;
//            case "Oracle":
//                userOperation = new OracleUserOperationImp();
//                break;
//            case "MySql":
//                break;
//        }

        //使用类加载器(反射)来动态加载指定的事先类,大大降低了dataAccess类和具体的实现类之间的耦合度
        String absolutePath = "Imp." + DB + "UserOperationImp";
//        Class<?> userOperationClass = ClassLoader.getSystemClassLoader().loadClass(absolutePath);
//        userOperation = ((IUserOperation) userOperationClass.newInstance());

        Class<?> userOperationClass = Class.forName(absolutePath);
        userOperation = ((IUserOperation) userOperationClass.newInstance());

        return userOperation;
    }

    public static IDepartmentOperation createDepartmentOperation(){
        IDepartmentOperation departmentOperation = null;
        switch (DB){
            case "SqlServer":
                departmentOperation = new SqlServerDepartmentOperationImp();
                break;
            case "Oracle":
                departmentOperation = new OracleDepartmentOperationImp();
                break;
            case "MySql":
                break;
        }
        return departmentOperation;
    }






}
